package com.evenmo.springjpademo.repository;

import com.evenmo.springjpademo.entity.User;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * This is Description User表操作接口，基于JPA实现DAO层（实现数据库的增删改查）
 *  两个泛型参数分别代表java POJO类以及主键数据类型
 * @author moyongjun
 * @date 2019/12/03
 */
@Repository
@Transactional(rollbackFor =Exception.class,isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED)//Spring事务隔离级别和回滚和事务传播特性
public interface UserRepository extends JpaRepository<User,Integer> {


    //自定义简单查询

   List<User> findByNameOrPassword(String name,String password);

   List<User> findByNameLike(String name);


    List<User> findALL(Pageable pageable);

    //自定义SQL查询，根据userName
    // 这里的User不是表名，而是pojo的类名，表示对象,里面不能用*（面向对象查询）
    @Query("select u from User u where u.name= :name")
    List<User> sleectByUserName(@Param("name") String name);//@Param(给name起了个标识符，使用时用：xxx即可)，这是hibernate参数设置的一种方式




    /**
    * @author: moyongjun
    * @Date: 2019/12/4 5:09 下午
    * @Description: 通过ID修改密码
    *
    */
    @Modifying(clearAutomatically = true)//自动清除过时的实体对象
//    @Transactional//自定义删除和更新需要事务的支持
    @Query("update User u set u.password=?1 where u.id=?2")//hibernate参数设置方式二，不起标识符，用？和占位符表示
   int updatePasswordById(String password,Integer id);

    /**
    * @author: moyongjun
    * @Date: 2019/12/4 5:09 下午
    * @Description: 将某些密码修改密码为指定的密码
    *
    */
    @Modifying(clearAutomatically = true)
//    @Transactional
    @Query("update User u set u.password=?1 where u.password=?2")
    int updateUserInfoByPassword(String newPassword,String oldPassword);

    //通过实体对象更新，字段非空时更新
    @Modifying(clearAutomatically = true)
    @Query("update User u set u.name=case when :#{#user.name} is null " +
            "then u.name else :#{#user.name} end ," +
            "u.password=case when :#{#user.password} is null " +
            "then u.password else :#{#user.password} end where u.id=:#{#user.id}")
    int updateUserInfo(@Param("user") User user);

}
